home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 11 / CU Amiga Magazine's Super CD-ROM 11 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-06].iso / cucd / sound / mp3 / src / libnix / musicout.c < prev   
C/C++ Source or Header  |  1997-03-02  |  25KB  |  752 lines

  1. /**********************************************************************
  2.  * ISO MPEG Audio Subgroup Software Simulation Group (1996)
  3.  * ISO 13818-3 MPEG-2 Audio Decoder - Lower Sampling Frequency Extension
  4.  *
  5.  * $Id: musicout.c,v 1.2 1996/03/28 03:13:37 rowlands Exp $
  6.  *
  7.  * $Log: musicout.c,v $
  8.  * Revision 1.2  1996/03/28 03:13:37  rowlands
  9.  * Merged layers 1-2 and layer 3 revisions
  10.  *
  11.  * Revision 1.1  1996/02/14 03:45:52  rowlands
  12.  * Initial revision
  13.  *
  14.  * Received from FhG
  15.  **********************************************************************/
  16. /**********************************************************************
  17.  *   date   programmers                comment                        *
  18.  * 2/25/91  Douglas Wong        start of version 1.0 records          *
  19.  * 3/06/91  Douglas Wong        rename setup.h to dedef.h             *
  20.  *                              removed extraneous variables          *
  21.  *                              removed window_samples (now part of   *
  22.  *                              filter_samples)                       *
  23.  * 3/07/91  Davis Pan           changed output file to "codmusic"     *
  24.  * 5/10/91  Vish (PRISM)        Ported to Macintosh and Unix.         *
  25.  *                              Incorporated new "out_fifo()" which   *
  26.  *                              writes out last incomplete buffer.    *
  27.  *                              Incorporated all AIFF routines which  *
  28.  *                              are also compatible with SUN.         *
  29.  *                              Incorporated user interface for       *
  30.  *                              specifying sound file names.          *
  31.  *                              Also incorporated user interface for  *
  32.  *                              writing AIFF compatible sound files.  *
  33.  * 27jun91  dpwe (Aware)        Added musicout and &sample_frames as  *
  34.  *                              args to out_fifo (were glob refs).    *
  35.  *                              Used new 'frame_params' struct.       *
  36.  *                              Clean,simplify, track clipped output  *
  37.  *                              and total bits/frame received.        *
  38.  * 7/10/91  Earle Jennings      changed to floats to FLOAT            *
  39.  *10/ 1/91  S.I. Sudharsanan,   Ported to IBM AIX platform.           *
  40.  *          Don H. Lee,                                               *
  41.  *          Peter W. Farrett                                          *
  42.  *10/ 3/91  Don H. Lee          implemented CRC-16 error protection   *
  43.  *                              newly introduced functions are        *
  44.  *                              buffer_CRC and recover_CRC_error      *
  45.  *                              Additions and revisions are marked    *
  46.  *                              with "dhl" for clarity                *
  47.  * 2/11/92  W. Joseph Carter    Ported new code to Macintosh.  Most   *
  48.  *                              important fixes involved changing     *
  49.  *                              16-bit ints to long or unsigned in    *
  50.  *                              bit alloc routines for quant of 65535 *
  51.  *                              and passing proper function args.     *
  52.  *                              Removed "Other Joint Stereo" option   *
  53.  *                              and made bitrate be total channel     *
  54.  *                              bitrate, irrespective of the mode.    *
  55.  *                              Fixed many small bugs & reorganized.  *
  56.  *19 aug 92 Soren H. Nielsen    Changed MS-DOS file name extensions.  *
  57.  * 8/27/93 Seymour Shlien,      Fixes in Unix and MSDOS ports,        *
  58.  *         Daniel Lauzon, and                                         *
  59.  *         Bill Truerniet                                             *
  60.  *--------------------------------------------------------------------*
  61.  * 4/23/92  J. Pineda           Added code for layer III.  LayerIII   *
  62.  *          Amit Gulati         decoding is currently performed in    *
  63.  *                              two-passes for ease of sideinfo and   *
  64.  *                              maindata buffering and decoding.      *
  65.  *                              The second (computation) pass is      *
  66.  *                              activated with "decode -3 <outfile>"  *
  67.  * 10/25/92 Amit Gulati         Modified usage() for layerIII         *
  68.  * 12/10/92 Amit Gulati         Changed processing order of re-order- *
  69.  *                              -ing step.  Fixed adjustment of       *
  70.  *                              main_data_end pointer to exclude      *
  71.  *                              side information.                     *
  72.  *  9/07/93 Toshiyuki Ishino    Integrated Layer III with Ver 3.9.    *
  73.  *--------------------------------------------------------------------*
  74.  * 11/20/93 Masahiro Iwadare    Integrated Layer III with Ver 4.0.    *
  75.  *--------------------------------------------------------------------*
  76.  *  7/14/94 Juergen Koller      Bug fixes in Layer III code           *
  77.  *--------------------------------------------------------------------*
  78.  * 08/11/94 IIS                 Bug fixes in Layer III code           *
  79.  *--------------------------------------------------------------------*
  80.  * 11/04/94 Jon Rowlands        Prototype fixes                       *
  81.  *--------------------------------------------------------------------*
  82.  *  7/12/95 Soeren H. Nielsen   Changes for LSF Layer I and II        *
  83.  *--------------------------------------------------------------------*
  84.  *  7/14/94 Juergen Koller      Bug fixes in Layer III code           *
  85.  *--------------------------------------------------------------------*
  86.  *     8/95 Roland Bitto        addapdet to MPEG 2                    *
  87.  *--------------------------------------------------------------------*
  88.  * 11/22/95 Heiko Purnhagen     skip ancillary data in bitstream      *
  89.  *--------------------------------------------------------------------*
  90.  * 12/16/96 Johan Hagman        Adapted for Solaris (mpeg3play 0.9)   *
  91.  **********************************************************************/
  92.  
  93. #include        "common.h"
  94. #include        "decoder.h"
  95. #include        "sound.h"
  96.  
  97. /********************************************************************
  98.  *
  99.  *        This part contains the MPEG I decoder for Layers I & II.
  100.  *
  101.  *********************************************************************/
  102.  
  103. /****************************************************************
  104.  *
  105.  *        For MS-DOS user (Turbo c) change all instance of malloc
  106.  *        to _farmalloc and free to _farfree. Compiler model hugh
  107.  *        Also make sure all the pointer specified are changed to far.
  108.  *
  109.  *****************************************************************/
  110. /* local functions definition */
  111.  
  112. static void usage(int level);
  113. static void GetArguments();
  114.  
  115. /*********************************************************************
  116.  *
  117.  * Core of the Layer II decoder.  Default layer is Layer II.
  118.  *
  119.  *********************************************************************/
  120.  
  121. /* Global variable definitions for "musicout.c" */
  122.  
  123. char            *programName;
  124. Arguments_t      Arguments;
  125. int              audiofd;
  126. /* Workaround for an audio buffer bug/restriction on Ultra/Solaris 2.5 */
  127. int              smallAudioBuffer = 0;
  128.  
  129. /* Implementations */
  130.  
  131. int main(int argc, char **argv)
  132. {
  133.     typedef unsigned int SAM[2][3][SBLIMIT];
  134.     static SAM FAR      *sample;
  135.  
  136.     typedef REAL         FRA[2][3][SBLIMIT];
  137.     static FRA FAR      *fraction;
  138.  
  139.     typedef short        PCMBUF[2][SSLIMIT][SBLIMIT];
  140.     static PCMBUF FAR   *pcm_sample;
  141.  
  142.     static Bit_stream_struc bs;
  143.     frame_params         fr_ps;
  144.     layer                info;
  145.     FILE                *musicout;              /* decode to file */
  146.     unsigned long        sample_frames;
  147.  
  148.     static int           i, j, k, stereo,
  149.              done = FALSE, clip, sync,
  150.              error_protection, crc_error_count,
  151.              total_error_count;
  152.     static unsigned int  old_crc, new_crc;
  153.     static unsigned int  bit_alloc[2][SBLIMIT],
  154.              scfsi[2][SBLIMIT],
  155.              scale_index[2][3][SBLIMIT];
  156.     unsigned long        bitsPerSlot = 0, samplesPerFrame = 0, frameNum = 0;
  157.     unsigned long        frameBits, gotBits = 0;
  158.     IFF_AIFF             pcm_aiff_data;
  159.     int                  Max_gr;
  160.  
  161.     III_scalefac_t       III_scalefac;
  162.     III_side_info_t      III_side_info;
  163.  
  164. #ifdef  MACINTOSH
  165.     console_options.nrows = MAC_WINDOW_SIZE;
  166.     argc = ccommand(&argv);
  167. #endif
  168.  
  169.     /* Most large variables are declared dynamically to ensure
  170.        compatibility with smaller machines */
  171.  
  172.     pcm_sample = (PCMBUF FAR *) mem_alloc((long) sizeof(PCMBUF),
  173.                           "PCM Sample");
  174.     sample = (SAM FAR *) mem_alloc((long) sizeof(SAM), "Sample");
  175.     fraction = (FRA FAR *) mem_alloc((long) sizeof(FRA), "fraction");
  176.  
  177.     fr_ps.header = &info;
  178.     fr_ps.tab_num = -1;                /* no table loaded */
  179.     fr_ps.alloc = NULL;
  180.  
  181.     Arguments.topSb = 0;
  182.     Arguments.forkoff = 0;
  183.     GetArguments(argc, argv, &Arguments);
  184.  
  185.     if (Arguments.forkoff) {
  186. #ifdef AMIGAL
  187.     fprintf(stderr, "fork not supported in libnix version\n",programName);
  188.     exit(1);
  189. #else
  190.     switch (fork()) {
  191.     case 0:
  192.         break;      /* child continues*/
  193.     case -1:
  194.         perror("fork");
  195.         exit(-1);
  196.         break;
  197.     default:
  198.         return 0;   /* parent returns*/
  199.     }
  200. #endif
  201.     }
  202.  
  203.     if (Arguments.write_to_file) {
  204.     if (strcmp(Arguments.decoded_file_name, "-") == 0)
  205.         musicout = stdout;
  206.     else {
  207. #ifdef AMIGAL
  208.         if ((musicout = fopen(Arguments.decoded_file_name, "wb" )) == NULL) {
  209.     /* libnix won't open a "w+b" file */
  210. #else
  211.         if ((musicout = fopen(Arguments.decoded_file_name, "w+b")) == NULL) {
  212. #endif
  213.         fprintf(stderr, "Could not create \"%s\".\n", Arguments.decoded_file_name);
  214.         exit(1);
  215.         }
  216.     }
  217.     } else {
  218.     /* Open audio device write-only (to avoid buffering input data) */
  219.     if( (audiofd = sound_open()) < 0) {
  220.         perror("open audio device");
  221.         exit(1);
  222.     }
  223.     }
  224.     open_bit_stream_r(&bs, Arguments.encoded_file_name, BUFFER_SIZE);
  225.  
  226.     if (Arguments.need_aiff)
  227.     if (aiff_seek_to_sound_data(musicout) == -1) {
  228.         if (strcmp(Arguments.decoded_file_name, "-") == 0)
  229.         fprintf(stderr, "Could not seek to PCM sound data in stdout\n");
  230.         else
  231.         fprintf(stderr, "Could not seek to PCM sound data in \"%s\"\n",
  232.             Arguments.decoded_file_name);
  233.         exit(1);
  234.     }
  235.  
  236.     sample_frames = 0;
  237.  
  238.     /* The output loop */
  239.     while (!end_bs(&bs)) {
  240.  
  241.     sync = seek_sync(&bs, SYNC_WORD, SYNC_WORD_LNGTH);
  242.     frameBits = sstell(&bs) - gotBits;
  243.     if (frameNum > 0)        /* don't want to print on 1st loop; no lay */
  244.         if(frameBits % bitsPerSlot)
  245.         fprintf(stderr, "Got %ld bits = %ld slots plus %ld\n",
  246.              frameBits, frameBits/bitsPerSlot, frameBits%bitsPerSlot);
  247.     gotBits += frameBits;
  248.  
  249.     if (!sync) {
  250.         if (Arguments.verbose) {
  251.         fprintf(stderr,
  252.             "\rFrame %ld cannot be located, input stream may be empty\n",
  253.             frameNum);
  254.         }
  255.         done = TRUE;
  256.         /* Finally write out the buffer */
  257.         if (info.lay != 1)
  258.         out_fifo(*pcm_sample, 3, &fr_ps, done, musicout,
  259.                 &sample_frames);
  260.         else
  261.         out_fifo(*pcm_sample, 1, &fr_ps, done, musicout,
  262.                 &sample_frames);
  263.         break;
  264.     }
  265.  
  266.     decode_info(&bs, &fr_ps);
  267.     hdr_to_frps(&fr_ps);
  268.     stereo = fr_ps.stereo;
  269.     if (fr_ps.header->version == MPEG_PHASE2_LSF)
  270.         Max_gr = 1;
  271.     else
  272.         Max_gr = 2;
  273.  
  274.     error_protection = info.error_protection;
  275.     crc_error_count = 0;
  276.     total_error_count = 0;
  277.  
  278.     if (frameNum == 0) {
  279.         if (Arguments.verbose)
  280.         WriteHdr(&fr_ps, stderr);       /* printout layer/mode */
  281.  
  282.         if (!Arguments.write_to_file) {
  283.         if (sound_init(audiofd, &info, stereo)) {
  284.             perror("Couldn't initialize sound device");
  285.             exit(1);
  286.         }
  287.         }
  288.     }
  289.  
  290. #ifdef ESPS
  291.     if (frameNum == 0 && Arguments.need_esps) {
  292.         esps_write_header(musicout,(long) sample_frames,
  293.         s_freq[info.version][info.sampling_frequency] * 1000,
  294.         (int) stereo, Arguments.decoded_file_name );
  295.     } /* MI */
  296. #endif
  297.  
  298.     if (Arguments.verbose && frameNum % 10 == 0) {
  299.         fprintf(stderr, "\rFrame %-3lu ", frameNum);
  300.     }
  301.  
  302.     frameNum++;
  303.  
  304.     if (error_protection)
  305.         buffer_CRC(&bs, &old_crc);
  306.  
  307.     switch(info.lay) {
  308.     case 1:
  309.         bitsPerSlot = 32;
  310.         samplesPerFrame = 384;
  311.  
  312.         I_decode_bitalloc(&bs,bit_alloc,&fr_ps);
  313.         I_decode_scale(&bs, bit_alloc, scale_index, &fr_ps);
  314.  
  315.         if (error_protection) {
  316.         I_CRC_calc(&fr_ps, bit_alloc, &new_crc);
  317.         if (new_crc != old_crc) {
  318.             crc_error_count++;
  319.             total_error_count++;
  320.             recover_CRC_error(*pcm_sample, crc_error_count,
  321.                     &fr_ps, musicout, &sample_frames);
  322.             break;
  323.         }
  324.         else crc_error_count = 0;
  325.         }
  326.  
  327.         clip = 0;
  328.         for (i = 0; i < SCALE_BLOCK; i++) {
  329.         I_buffer_sample(&bs, (*sample), bit_alloc,&fr_ps);
  330.         I_dequantize_sample(*sample, *fraction, bit_alloc,&fr_ps);
  331.         I_denormalize_sample((*fraction),scale_index,&fr_ps);
  332.  
  333.         if (Arguments.topSb > 0)     /* clear channels to 0 */
  334.            for (j = Arguments.topSb; j < fr_ps.sblimit; ++j)
  335.               for (k = 0; k < stereo; ++k)
  336.              (*fraction)[k][0][j] = 0.0;
  337.  
  338.         for (j = 0; j < stereo; j++) {
  339.            clip += SubBandSynthesis(&((*fraction)[j][0][0]), j,
  340.                          &((*pcm_sample)[j][0][0]));
  341.         }
  342.         out_fifo(*pcm_sample, 1, &fr_ps, done,
  343.              musicout, &sample_frames);
  344.          }
  345.          if (clip > 0 && Arguments.verbose)
  346.         fprintf(stderr, "\rFrame %-3lu: %d output samples clipped\n",
  347.                 frameNum - 1, clip);
  348.          break;
  349.  
  350.     case 2:
  351.         bitsPerSlot = 8;
  352.         samplesPerFrame = 1152;
  353.  
  354.         II_decode_bitalloc(&bs, bit_alloc, &fr_ps);
  355.         II_decode_scale(&bs, scfsi, bit_alloc, scale_index, &fr_ps);
  356.  
  357.         if (error_protection) { 
  358.         II_CRC_calc(&fr_ps, bit_alloc, scfsi, &new_crc);
  359.         if (new_crc != old_crc) {
  360.             crc_error_count++;
  361.             total_error_count++;
  362.             recover_CRC_error(*pcm_sample, crc_error_count,
  363.                 &fr_ps, musicout, &sample_frames);
  364.             break;
  365.         } else
  366.             crc_error_count = 0;
  367.          }
  368.  
  369.          clip = 0;
  370.          for (i = 0; i < SCALE_BLOCK; i++) {        /* SCALE_BLOCK = 12*/
  371.         II_buffer_sample(&bs, (*sample), bit_alloc, &fr_ps);
  372.         II_dequantize_sample((*sample), bit_alloc, (*fraction), &fr_ps);
  373.         II_denormalize_sample((*fraction), scale_index, &fr_ps, i>>2);
  374. #ifdef DEBUG
  375.         if (Arguments.topSb > 0)      /* debug : clear channels to 0 */
  376.             for (j=Arguments.topSb; j<fr_ps.sblimit; ++j)
  377.             for (k=0; k<stereo; ++k)
  378.                 (*fraction)[k][0][j] =
  379.                 (*fraction)[k][1][j] =
  380.                 (*fraction)[k][2][j] = 0.0;
  381. #endif
  382.         for (j = 0; j < 3; j++) {
  383.             for (k = 0; k < stereo; k++) {
  384.             clip += SubBandSynthesis(&((*fraction)[k][j][0]),
  385.                 k, &((*pcm_sample)[k][j][0]));
  386.             }
  387.         }
  388.         out_fifo(*pcm_sample, 3, &fr_ps, done, musicout,
  389.              &sample_frames);
  390.          }
  391.          if (clip > 0 && Arguments.verbose)
  392.         fprintf(stderr, "\rFrame %-3lu: %d output samples clipped\n",
  393.                 frameNum - 1, clip);
  394.          break;
  395.  
  396.     case 3: {
  397.         static int  nSlots;
  398.         static int  gr, ch, ss, sb,
  399.             main_data_end, flush_main;
  400.         static int  bytes_to_discard;
  401.         static int  frame_start = 0;
  402.  
  403.         bitsPerSlot = 8;         
  404.         if (fr_ps.header->version == MPEG_PHASE2_LSF)
  405.         samplesPerFrame = 576;
  406.         else
  407.         samplesPerFrame = 1152;
  408.  
  409.         III_get_side_info(&bs, &III_side_info, &fr_ps);
  410.         nSlots = main_data_slots(fr_ps);
  411.  
  412.         for (; nSlots > 0; nSlots--)        /* read main data*/
  413.         hputbuf((unsigned int) getbits(&bs,8), 8);
  414.         main_data_end = hsstell() / 8;      /* of previous frame*/
  415.  
  416.         if ((flush_main = (hsstell() % bitsPerSlot))) { 
  417.         hgetbits((int)(bitsPerSlot - flush_main));
  418.         main_data_end ++;
  419.         }
  420.         bytes_to_discard = frame_start - main_data_end -
  421.                    III_side_info.main_data_begin ;
  422.         if (main_data_end > 4096) {
  423.         frame_start -= 4096;
  424.         rewindNbytes(4096);
  425.         }
  426.  
  427.         frame_start += main_data_slots(fr_ps);
  428.         if (bytes_to_discard < 0) {
  429.         if (Arguments.verbose)
  430.             fprintf(stderr, "not enough main data to decode, "
  431.                  "frame discarded\n");
  432.         break;
  433.         }
  434.         for (; bytes_to_discard > 0; bytes_to_discard--)
  435.          hgetbits(8);
  436.  
  437.         clip = 0;
  438.         for (gr = 0; gr < Max_gr; gr++) {   /* 1 or 2*/
  439.         static REAL     lr[2][SBLIMIT][SSLIMIT],
  440.                 ro[2][SBLIMIT][SSLIMIT];
  441.  
  442.         for (ch = 0; ch < stereo; ch++) {
  443.             /* Quantized samples*/
  444.             static long int is[SBLIMIT+1][SSLIMIT];
  445.             int part2_start;
  446.  
  447.             part2_start = hsstell();
  448.             if (fr_ps.header->version != MPEG_PHASE2_LSF)
  449.             III_get_scale_factors(&III_scalefac,
  450.                 &III_side_info, gr, ch, &fr_ps);
  451.             else
  452.             III_get_LSF_scale_factors(&III_scalefac,
  453.                 &III_side_info, gr,ch,&fr_ps);
  454.  
  455.             III_hufman_decode(is, &III_side_info, ch, gr, part2_start,
  456.                 &fr_ps);
  457.             III_dequantize_sample(is, ro[ch], &III_scalefac,
  458.                 &(III_side_info.ch[ch].gr[gr]), ch, &fr_ps);
  459.         }
  460.         III_stereo(ro, lr, &III_scalefac,
  461.                 &(III_side_info.ch[0].gr[gr]), &fr_ps);
  462.  
  463.         for (ch = 0; ch < stereo; ch++) {
  464.             static REAL re[SBLIMIT][SSLIMIT];
  465.             /* Hybrid filter input*/
  466.             static REAL hybridIn[SBLIMIT][SSLIMIT];
  467.             /* Hybrid filter out*/
  468.             static REAL hybridOut[SBLIMIT][SSLIMIT];
  469.             /* PolyPhase Input*/
  470.             static REAL polyPhaseIn[SBLIMIT];
  471.  
  472.             III_reorder(lr[ch],re,&(III_side_info.ch[ch].gr[gr]),
  473.                   &fr_ps);
  474.  
  475.             III_antialias(re, hybridIn,         /* antialias butterflies*/
  476.                   &(III_side_info.ch[ch].gr[gr]), &fr_ps);
  477.  
  478.             for (sb = 0; sb < SBLIMIT; sb++) {  /* hybrid synthesis*/
  479.             III_hybrid(hybridIn[sb], hybridOut[sb], sb, ch,
  480.                    &(III_side_info.ch[ch].gr[gr]), &fr_ps);
  481.             }
  482.  
  483. #ifdef OPTIMIZE
  484.             for (ss = 0; ss < SSLIMIT; ss++) {  /* Polyphase synthesis*/
  485.             for (sb = 0; sb < SBLIMIT; sb++) {
  486.                 /* Perform frequency inversion for polyphase*/
  487.                 if ((ss % 2) && (sb % 2))
  488.                 polyPhaseIn[sb] = -hybridOut[sb][ss];
  489.                 else
  490.                 polyPhaseIn[sb] = hybridOut[sb][ss];
  491.             }
  492.             clip += SubBandSynthesis(polyPhaseIn, ch,
  493.                         &((*pcm_sample)[ch][ss][0]));
  494.             }
  495. #else
  496.             /* Frequency inversion for polyphase*/
  497.             for (ss = 0; ss < SSLIMIT; ss++)            /* 18*/
  498.             for (sb = 0; sb < SBLIMIT; sb++)        /* 32*/
  499.                 if ((ss%2) && (sb%2))
  500.                 hybridOut[sb][ss] = -hybridOut[sb][ss];
  501.  
  502.             for (ss = 0; ss < SSLIMIT; ss++) {  /* Polyphase synthesis*/
  503.             for (sb = 0; sb < SBLIMIT; sb++)
  504.                 polyPhaseIn[sb] = hybridOut[sb][ss];
  505.             clip += SubBandSynthesis (polyPhaseIn, ch,
  506.                         &((*pcm_sample)[ch][ss][0]));
  507.             }
  508. #endif  /* OPTIMIZE */
  509.         }
  510.         /* Output PCM sample points for one granule*/
  511.         out_fifo(*pcm_sample, 18, &fr_ps, done, musicout,
  512.              &sample_frames);
  513.         }
  514.         if (clip > 0 && Arguments.verbose)
  515.         fprintf(stderr, "\rFrame %-3lu: %d output samples clipped\n",
  516.                 frameNum - 1, clip);
  517.  
  518.         } /* end of layer 3 block*/
  519.         break;
  520.  
  521.     } /* end of case*/
  522.  
  523. /* Commented out for now*/
  524. #if 0
  525.     /* Skip ancillary data   HP 22-nov-95 */
  526.     if (info.bitrate_index > 0) { /* if not free-format */
  527.         long anc_len;
  528.  
  529.         anc_len = (int)((double)samplesPerFrame /
  530.                    s_freq[info.version][info.sampling_frequency] *
  531.                    (double)bitrate[info.version][info.lay-1][info.bitrate_index] /
  532.                    (double)bitsPerSlot);
  533.         if (info.padding)
  534.             anc_len++;
  535.         anc_len *= bitsPerSlot;
  536.         anc_len -= sstell(&bs)-gotBits+SYNC_WORD_LNGTH;
  537.         for (j=0; j<anc_len; j++)
  538.             get1bit(&bs);
  539.     }
  540. #endif
  541.  
  542.     }
  543.  
  544.     if (Arguments.need_aiff) {
  545.     pcm_aiff_data.numChannels       = stereo;
  546.     pcm_aiff_data.numSampleFrames   = sample_frames;
  547.     pcm_aiff_data.sampleSize        = 16;
  548.     pcm_aiff_data.sampleRate        = (double)
  549.         s_freq[info.version][info.sampling_frequency] * 1000;
  550.     pcm_aiff_data.sampleType        = IFF_ID_SSND;
  551.     pcm_aiff_data.blkAlgn.offset    = 0;
  552.     pcm_aiff_data.blkAlgn.blockSize = 0;
  553.  
  554.     if (aiff_write_headers(musicout, &pcm_aiff_data) == -1) {
  555.         if (strcmp(Arguments.decoded_file_name, "-") == 0)
  556.         fprintf(stderr, "Could not write AIFF headers to stdout\n");
  557.         else
  558.         fprintf(stderr, "Could not write AIFF headers to \"%s\"\n",
  559.             Arguments.decoded_file_name);
  560.         exit(2);
  561.     }
  562.     }
  563.  
  564.     if (Arguments.verbose)
  565.     fprintf(stderr, "\r%ld frames, avg slots/frame = %.3f; b/smp = %.2f; br = %.3f kbps\n",
  566.         frameNum, (float) gotBits / (frameNum * bitsPerSlot),
  567.         (float) gotBits / (frameNum * samplesPerFrame),
  568.         (float) gotBits / (frameNum * samplesPerFrame) *
  569.         s_freq[info.version][info.sampling_frequency]);
  570.  
  571.     close_bit_stream_r(&bs);
  572.     if (Arguments.write_to_file)
  573.     fclose(musicout);
  574.     else {
  575.     if (sound_close(audiofd))
  576.         perror("Error closing audio device");
  577.     }
  578.  
  579.     /* for the correct AIFF header information */
  580.     /*             on the Macintosh            */
  581.     /* the file type and the file creator for  */
  582.     /* Macintosh compatible Digidesign is set  */
  583.  
  584. #ifdef  MACINTOSH
  585.     if (Arguments.need_aiff)
  586.         set_mac_file_attr(Arguments.decoded_file_name, VOL_REF_NUM,
  587.                      CREATR_DEC_AIFF, FILTYP_DEC_AIFF);
  588.     else        set_mac_file_attr(Arguments.decoded_file_name, VOL_REF_NUM,
  589.                      CREATR_DEC_BNRY, FILTYP_DEC_BNRY);
  590. #endif
  591.  
  592.     if (Arguments.verbose) {
  593.     fprintf(stderr, "Decoding of \"%s\" is finished\n",
  594.         Arguments.encoded_file_name);
  595.     if (Arguments.write_to_file) {
  596.         if (strcmp(Arguments.decoded_file_name, "-") == 0)
  597.         fprintf(stderr, "The decoded PCM output was written to stdout\n");
  598.         else
  599.         fprintf(stderr, "The decoded PCM output file name is \"%s\"\n",
  600.             Arguments.decoded_file_name);
  601.     }
  602.     }
  603.     return 0;
  604. }
  605.  
  606. static void usage(int level)    /* print help info and exit*/
  607. {
  608.     if (level >= 1) {
  609.     fprintf(stderr,
  610.     "+----------------------------------------+\n"
  611.     "|   mpeg3play version 0.9.5, 23-Feb-97   |\n"
  612.     "+----------------------------------------+\n"
  613.     "This is an MPEG audio layer 2 and layer 3 decoder/player\n"
  614.     "based on public ISO/MPEG audio decoder source code. Solaris\n"
  615.     "port and optimizations by Johan.Hagman@mailbox.swipnet.se.\n\n"
  616.     "Copyright (C) 1996, 1997 by Johan Hagman.\n"
  617.     "This program is free software.\n\n");
  618.     }
  619. #ifdef DEBUG
  620.     fprintf(stderr, "usage: %s [-v] [-h] [-f] [-o outfile.aiff] [-s sb] filename\n",
  621.         programName);
  622. #else
  623.     fprintf(stderr, "usage: %s [-v] [-h] [-f] [-o outfile.aiff] filename\n",
  624.         programName);
  625. #endif
  626.     fprintf(stderr,"  -v          enable verbose mode\n");
  627.     fprintf(stderr,"  -h          display program help information\n");
  628.     fprintf(stderr,"  -f          fork off new player and return\n");
  629. #ifdef AMIGA
  630.     fprintf(stderr,"  -r          switch to raw PCM (amiga)\n");
  631. #endif
  632.     fprintf(stderr,"  -o outfile  write an AIFF output PCM sound file\n");
  633. #ifdef DEBUG
  634.     fprintf(stderr,"  -s sb       resynth only up to this subband (debugging)\n");
  635. #endif
  636.     fprintf(stderr,"  filename    bit stream of encoded audio (\"-\" means stdin)\n");
  637.     exit(1);
  638. }
  639.  
  640.  
  641. static void GetArguments(int argc, char **argv, Arguments_t *Arguments)
  642. {
  643.     int         i = 0, err = 0;
  644.  
  645.     programName = "mpeg3play";
  646.  
  647.     Arguments->need_aiff = TRUE;
  648.     Arguments->need_esps = FALSE;       /* MI */
  649.     Arguments->write_to_file= FALSE;
  650.     Arguments->verbose = FALSE;
  651.  
  652.     Arguments->encoded_file_name[0] = '\0';
  653.     Arguments->decoded_file_name[0] = '\0';
  654.  
  655.     while (++i < argc && err == 0) {
  656.     char c, *token, *arg, *nextArg;
  657.     int  argUsed;
  658.  
  659.     token = argv[i];
  660.     /* Original code was if (*token++ == '-'), this change makes*/
  661.     /* it possible to use "-" for reading input stream from stdin*/
  662.     if (*token++ == '-' && *token != '\0') {
  663.         if (i+1 < argc)
  664.         nextArg = argv[i+1];
  665.         else
  666.         nextArg = "";
  667.         argUsed = 0;
  668.         while ((c = *token++)) {
  669.         if (*token /* NumericQ(token) */)
  670.             arg = token;
  671.         else
  672.             arg = nextArg;
  673.         switch(c) {
  674.         case 'v':
  675.             Arguments->verbose = TRUE;
  676.             break;
  677.         case 'h':
  678.             usage(1);
  679.             break;
  680.         case 'f':
  681.             Arguments->forkoff = TRUE;
  682.             break;
  683. #ifdef AMIGA
  684.         case 'r':
  685.             Arguments->need_aiff = FALSE;
  686.             break;
  687. #endif
  688.         case 'o':
  689.             argUsed = 1;        /* eat one arg*/
  690.             if (*arg == '\0') {
  691.             fprintf(stderr,"error: -o requires a filename arg\n");
  692.             err = 1;        /* found no filename*/
  693.             } else {
  694.             strcpy(Arguments->decoded_file_name, arg);
  695.             /* Arguments->need_aiff = TRUE; */
  696.             Arguments->write_to_file = TRUE;
  697.             }
  698.             break;
  699. #ifdef DEBUG
  700.         case 's':
  701.             Arguments->topSb = atoi(arg);
  702.             argUsed = 1;
  703.             if (Arguments->topSb<1 || Arguments->topSb>SBLIMIT) {
  704.             fprintf(stderr, "%s: -s band %s not %d..%d\n",
  705.                     programName, arg, 1, SBLIMIT);
  706.             err = 1;
  707.             }
  708.             break;
  709. #endif
  710.         default:
  711.             fprintf(stderr,"error: unrecognized option \"%c\"\n", c);
  712.             err = 1;
  713.             break;
  714.         }
  715.         if (argUsed) {
  716.             if (arg == token)
  717.             token = "";     /* no more from token */
  718.             else
  719.             ++i;            /* skip arg we used */
  720.             arg = "";
  721.             argUsed = 0;
  722.         }
  723.         } /* end while*/
  724.  
  725.     } else { /* end of options*/
  726.  
  727.         if (Arguments->encoded_file_name[0] == '\0') {
  728.         strcpy(Arguments->encoded_file_name, argv[i]);
  729.         } else {
  730.         fprintf(stderr, "error: excess arg \"%s\"\n", argv[i]);
  731.         err = 1;
  732.         }
  733.     }
  734.  
  735.     }
  736.  
  737.     if (err)
  738.     usage(0);
  739.     if (Arguments->encoded_file_name[0] == '\0') {
  740.     fprintf(stderr, "error: input file is missing\n");
  741.     usage(0);  /* never returns */
  742.     }
  743.  
  744.     if (Arguments->verbose && Arguments->need_aiff) {
  745.     if (strcmp(Arguments->decoded_file_name, "-") == 0)
  746.         fprintf(stderr, "The AIFF audio data is written to stdout\n");
  747.     else
  748.         fprintf(stderr, "The output file \"%s\" is written in AIFF format\n",
  749.             Arguments->decoded_file_name);
  750.     }
  751. }
  752.